﻿        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.Drawing;
        using System.Media;
        using System.Net;
        using System.Net.Sockets;
        using System.Runtime.InteropServices;
        using System.Text;
        using System.Threading;
        using System.Windows.Forms;
        using Stone_Jumper.Properties;
        using Timer = System.Windows.Forms.Timer;

namespace Stone_Jumper
{
    


    public class Game : Form
        {


            private IContainer components;
            private bool gameIsPaused=false;
            private float speed;
            private string countDownText;
        
            private MySize formSize= new MySize() {Height = 700, Width = 600};
            private Bars bars;

        public bool HasToClose {
            get { return hasToClose; }
            set { hasToClose = value; }
        }


        private bool hasToClose;
            private Jumper jumper;
            private Random r = new Random();
            public int score;

            private MainMenu mainMenu;
            private Thread threadBarMover;
            private Thread threadCountDown;
            private Thread threadDecreaseSpeed;
            private Thread threadGravity;
            private Thread threadInvalidate;
            private Thread threadPlayerBounds;
            private Thread ConsoleOutLine;
            private Image youHorizontal;
        
         
           
            private Gravity gr;
            private Timer timer;

            public void GameOver(object sender,EventArgs e)
            {
                hasToClose = true;
              
               mainMenu.Show();
               
               mainMenu.Focus();
              
            }

            public Game(MainMenu main)
            {
                this.InitializeComponent();
                base.Paint += new PaintEventHandler(this.Game_Paint);
                base.Load += new EventHandler(this.Game_Load);
                mainMenu = main;
                

                PreviewKeyDown += PauseGame;
           
              
                youHorizontal = Resources.YouRight;

                timer=new Timer(){Interval = 1};
           

                this.Show();
                while (!this.hasToClose)
                {
                    Application.DoEvents();
                }
                this.Close();
              


            }

   

            public void CountDown()
            {
                this.countDownText = "READY";
                base.Invalidate();
                Thread.Sleep(1500);
                this.countDownText = "SET";
                base.Invalidate();
                new SoundPlayer(Resources.Start).Play();
                Thread.Sleep(1500);
                this.countDownText = "GO!";
                base.Invalidate();
                this.startThreads();
                
                Thread.Sleep(2500);
                this.countDownText = "";
                base.Invalidate();
            }

            private void decreaseSpeed()
            {
                bool flag = true;
                while (flag)
                {
                    Thread.Sleep(0x3e8);
                    if (this.speed >= 2f)
                    {
                        this.speed -= 0.01f;
                    }
                }
            }

           

            private void Game_Load(object sender, EventArgs e)
            {
                
                this.InitForm();
                jumper = new Jumper(new PointF(0, 0), new MySize() { Height = 90, Width = 60 }, new MySize() { Height = 10, Width = 100 }, new MySize() { Height = this.Height, Width = this.Width },this);
                gr = new Gravity();
                bars = new Bars(formSize);
                this.InitYou();
                this.threadCountDown = new Thread(new ThreadStart(this.CountDown));
                this.threadCountDown.Start();
            }

            private void Game_Paint(object sender, PaintEventArgs e)
            {
                this.Size=new Size(700,600);
                e.Graphics.DrawImage(Properties.Resources.background,new PointF(0,0));
                for (int i = 0; i < (this.bars.ShownBars.Count); i++)
                {
                    e.Graphics.DrawImage(Resources.Bar, bars.ShownBars[i]);
                }
                
                e.Graphics.DrawImage(this.youHorizontal, this.jumper.position);
                e.Graphics.DrawString("Score: " + Math.Round((decimal)(this.score / 10M)), new Font("Motorwerk", 20f, FontStyle.Regular), Brushes.Black, (PointF)new Point(10, 10));
                if (this.countDownText != "")
                {
                    e.Graphics.DrawString(this.countDownText, new Font("Motorwerk", 32f, FontStyle.Bold), Brushes.Black, (PointF)new Point((base.Width / 2) - 50, base.Height / 4));
                }
                base.SetStyle(ControlStyles.DoubleBuffer, true);
                base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
                base.SetStyle(ControlStyles.UserPaint, true);
            }

            [DllImport("user32.dll")]
            public static extern short GetAsyncKeyState(Keys vKeys);
            private void Gravity()
            {
                while (true)
                {
                    Thread.Sleep(2);
                    jumper.CheckForBounce(bars.ShownBars);
                    gr.MakeGravity(jumper);
                }
            }

            

            private void InitForm()
            {
                this.components = new Container();
                base.FormBorderStyle = FormBorderStyle.None;
                base.Size = new Size(this.formSize.Width,this.formSize.Height);
                base.CenterToScreen();
            }

            private void InitializeComponent()
            {
            this.SuspendLayout();
            // 
            // Game
            // 
            this.ClientSize = new System.Drawing.Size(284, 261);
            this.Name = "Game";
            this.Text = "Game";
           
            this.ResumeLayout(false);

            }

            private void InitYou()
            {
                jumper.position = this.bars.ShownBars[1];
                jumper.position.X += this.r.Next(0, 100 - this.jumper.JumperSize.Width);
                jumper.position.Y -= this.r.Next(this.jumper.JumperSize.Height + 4, this.jumper.JumperSize.Height + 13);
                if (this.r.Next(0, 2) == 0)
                {
                    this.youHorizontal =(Stone_Jumper.Properties.Resources.YouRight);
                }
                else
                {
                    this.youHorizontal = Stone_Jumper.Properties.Resources.YouLeft;
                }
          
            }

            private void InvalidateForm()
            {
                while (true)
                {
                    Control.CheckForIllegalCrossThreadCalls = false;
                    base.Invalidate();
                    if (!this.hasToClose)
                    {
                     continue;
                    }
                    try
                    {
                        this.killThreads();
                        this.hasToClose = false;
                        base.Close();
                        continue;
                        
                    }
                    catch (Exception exception)
                    {
                        exception.ToString();
                     
                    }
                    
                }
                
            }

            private void killThreads()
            {
                this.threadBarMover.Abort();
                this.threadGravity.Abort();
                this.threadDecreaseSpeed.Abort();
                this.threadPlayerBounds.Abort();
                this.threadInvalidate.Abort();
                this.threadCountDown.Abort();
            }

            private void moveBarsDown()
            {
                float num = 0f;
                while (true)
                {Thread.Sleep(15);
                    bars.MoveBarsDown();
                    num += bars.Speed;
                    this.score += Convert.ToInt32(this.speed);
                }
            }

            private void playerBounds()
            {
                while (true)
                {
                    Thread.Sleep(1);
                    jumper.PlayerBounds();
                    if (GetAsyncKeyState(Keys.Left) == -32768)
                    {
                        this.youHorizontal = Stone_Jumper.Properties.Resources.YouLeft;
                        jumper.position.X -= 0.5f;
                   
                    }
                    else if (GetAsyncKeyState(Keys.Right) == -32768)
                    {
                        this.youHorizontal = Stone_Jumper.Properties.Resources.YouRight;
                        jumper.position.X += 0.5f;
                     
                    }
                }
            }

            protected override void Dispose(bool disposing)
            {
                if (disposing && (this.components != null))
                {
                    this.components.Dispose();
                }
                base.Dispose(disposing);
            }

            private void PauseGame(object sender, PreviewKeyDownEventArgs e)
            {
                var menuInGame = new MenuInGame(mainMenu, this);
                if(e.KeyCode==Keys.Escape)
                {
                    if (!gameIsPaused)
                    {
                        this.threadBarMover.Suspend();
                        this.threadGravity.Suspend();
                        this.threadDecreaseSpeed.Suspend();
                        this.threadPlayerBounds.Suspend();
                        this.threadInvalidate.Suspend();
                        
                        menuInGame.Show();
                        base.Invalidate();

                    }
                    else
                    {
                        if (gameIsPaused)
                        {
                            this.threadBarMover.Resume();
                            this.threadGravity.Resume();
                            this.threadDecreaseSpeed.Resume();
                            this.threadPlayerBounds.Resume();
                            this.threadInvalidate.Resume();

                            menuInGame.Hide();
                            base.Invalidate();
                        }

                    }
                    gameIsPaused = !gameIsPaused;
                }
            }

            private void startThreads()
            {
                this.threadInvalidate = new Thread(new ThreadStart(this.InvalidateForm));
                this.threadBarMover = new Thread(new ThreadStart(this.moveBarsDown));
                this.threadGravity = new Thread(new ThreadStart(this.Gravity));
                this.threadDecreaseSpeed = new Thread(new ThreadStart(this.decreaseSpeed));
                this.threadPlayerBounds = new Thread(new ThreadStart(this.playerBounds));
            
            
                this.threadBarMover.Start();
                this.threadGravity.Start();
                this.threadDecreaseSpeed.Start();
                this.threadPlayerBounds.Start();
                this.threadInvalidate.Start();
                this.speed = 1f;
            }

          
            
        }
    }

